home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Graphics Plus
/
Graphics Plus.iso
/
general
/
modelers
/
nff
/
filter.c
next >
Wrap
Internet Message Format
|
1992-12-02
|
6KB
From pkh@vap.vi.ri.cmu.edu Tue Dec 13 21:30:04 1988
Path: leah!itsgw!sun.soe.clarkson.edu!batcomputer!cornell!rochester!pt.cs.cmu.edu!vap.vi.ri.cmu.edu!pkh
From: pkh@vap.vi.ri.cmu.edu (Ping Kang Hsiung)
Newsgroups: comp.graphics
Subject: nff filter for redundant polygon vertices
Message-ID: <3865@pt.cs.cmu.edu>
Date: 14 Dec 88 02:30:04 GMT
Organization: Carnegie-Mellon University, CS/RI
Lines: 244
I am posting the source code since among the people
who requested for the source code, two of them are
not reach-able from my system. Fortunately it's not a
big program. Sorry for the inconvenience.
***
/*
* program: nfff.c
*
* a filter for NFF (Neutral File Format)
* nfff [infile]
* input: infile.nff or stdin
* output: stdout
*
* input items other than polygons are copied to output directly.
* for polygons that have 2 or more identical vertices, the redundant
* vertices are filtered out and the "p <vert_count>" lines of
* the polygons are adjusted properly.
*
* the vertices degeneration cases occur in data produced by some
* automatic nff generation program when the resolution/prec. of
* generation exceeds that of the floating point format.
*
* definition of NFF: see nff.def
* bugs:
* (1) handles polygons only. break if there are other obj. types
* (2) MAX_VERT may cause trouble
*
* Fri Dec 2 16:41:27 EST 1988
* pkh@vap
*
* bugs fixed:
*
*/
#include <stdio.h>
#include <math.h>
/* #include "/usr/pkh/include/all.h" */
/* #include "/usr/pkh/include/def3d.h" */
/* from "def3d.h" */
typedef struct pt3d_struct {
float x, y, z;
} pt3d, *pt3d_t;
#define FPRINT3d(fp, pt, newline) do { \
if (newline) \
fprintf(fp, "%g %g %g\n", pt.x, pt.y, pt.z); \
else \
fprintf(fp, "%g %g %g", pt.x, pt.y, pt.z); \
} while (0)
#define FSCAN3d(fp, pt) do { \
fscanf(fp,"%f %f %f", &(pt.x), &(pt.y), &(pt.z)); \
} while(0)
#define ASSIGN3d(p0, p1) do {p0.x=p1.x; p0.y=p1.y; p0.z=p1.z;} while(0)
#define EQ3d(p0, p1) ((p0.x==p1.x)&&(p0.y==p1.y)&& (p0.z==p1.z))
/* from "all.h" */
int debug;
#define POW2(y) (1<<y)
#define ERROR_MSG_LENGTH (200)
#define DEBUG(arg) \
do { \
char msg[ERROR_MSG_LENGTH]; \
if (debug) { \
sprintf arg; \
fprintf(stderr, "%s", msg); \
} \
} while (0)
#define ERROR(arg) \
do { \
char msg[ERROR_MSG_LENGTH]; \
sprintf arg; \
fprintf(stderr, "%s", msg); \
exit(0); \
} while (0)
#define MAX_VERT POW2(12) /* 4k verts per poly */
pt3d *v; /* array of dim MAX_VERT */
FILE *nfffile;
char infile[25];
/*
* for statistics
*/
int total_byte; /* total byte allocated */
int poly_id;
/*
* copy to end of line
*/
copy_line(ifp, ofp)
FILE *ifp, *ofp;
{
char c;
do {
putc((c=getc(ifp)), ofp);
} while (c!='\n');
}
int read_poly(fp)
FILE *fp;
{
int tv;
int i;
fscanf(fp, "%d", &tv);
for (i = 0; i < tv; i++) {
FSCAN3d(fp,(v[i]));
}
return (tv);
}
/*
* filter out degenerated (redundant) vertices
* and return the true vert count.
* complain when polygon has less than 3 vert
*/
int vert_filter(in_vert)
int in_vert;
{
int head, tail;
int tv, skip;
/*
* filter out degenerated vertices. head points to the verified vert,
* tail scans down the vert list for new vert.
*/
head = 0; /* points to v[0] */
tail = head + 1; /* points to v[1] */
tv = 1; /* count one vert already (v[0]) */
skip = 0; /* "skip occured" flag */
do {
while (EQ3d((v[head]), (v[tail]))) {
tail++;
if (tail == in_vert)
goto last_vert;
skip = 1;
}
if (skip) {
ASSIGN3d((v[head + 1]), (v[tail]));
}
head++;
tail++;
} while (tail < in_vert);
/* head now points to the last valid vert. compare last and first */
last_vert:if (EQ3d((v[0]), v[head]))
tv = head;
else
tv = head + 1;
if (tv < 3) {
ERROR((msg, "poly %d has less than 3 vert\n", poly_id));
write_polygon(stderr, tv); /* write vert */
}
if (debug) {
write_polygon(stderr, tv); /* write vert */
}
return (tv);
}
/*
* write out the cleaned-up polygons in nff format
* also print out the poly id
*/
write_polygon(fp, ply_vert)
FILE *fp;
int ply_vert;
{
int j;
fprintf(fp, "# p%d\np %d\n", poly_id, ply_vert);
for (j = 0; j < ply_vert; j++) {
FPRINT3d(fp, (v[j]), 0);
fprintf(fp, "\n");
}
}
/*
* for polygons: read-filter-write
* for the rest: read-write
*/
read_write(ifp, ofp)
FILE *ifp, *ofp;
{
char key[20];
int in_vert, out_vert;
/* read "key" */
while (fscanf(ifp, "%s", key) != EOF) {
DEBUG((msg, "get key %s\n", key));
if (strcmp(key, "p") == 0) {
in_vert = read_poly(ifp);
out_vert = vert_filter(in_vert);
write_polygon(ofp, out_vert);
poly_id++;
} else {
fprintf(ofp, "%s ", key);
copy_line(ifp, ofp);
}
};
}
init()
{
int new_byte;
new_byte = sizeof(pt3d) * MAX_VERT;
total_byte += new_byte;
v = (pt3d_t) malloc(new_byte);
DEBUG((msg, "v alloc %3dB; total %5dB\n", new_byte, total_byte));
if (v == NULL)
ERROR((msg, "v array alloc err\n"));
poly_id = 0;
}
main(argc, argv)
int argc;
char *argv[];
{
if (argc == 1) {
nfffile= stdin;
}
else if (argc == 2) {
/* ap
}pend .nff suffix */
sprintf(infile, "%s.nff", argv[1]);
if ((nfffile= fopen(infile, "r")) == NULL) {
ERROR((msg, "input file %s not found\n", infile));
exit(1);
}
} else {
ERROR((msg, "Usage: %s [file].nff\n", argv[0]));
exit(1);
}
debug = 0;
init();
fprintf(stdout, "#\n# polygons filtered by nfffilter program\n");
fprintf(stdout, "# date:\n#\n");
read_write(nfffile, stdout);
}